﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace AirTickets
{
    [Serializable()]
    public class Vuelo:IComparable
    {

        protected string _codigo;
        protected DateTime _fecha_salida;
        protected DateTime _fecha_llegada;
        protected Avion _avion;
        protected Aeropuerto _aeropuerto_origen;
        protected Aeropuerto _aeropuerto_destino;
        protected List<Billete> _billetes;
        protected internal List<Billete> Billetes { get { return _billetes; } }

        public string Codigo { get { return _codigo; } }

        
        public Vuelo()
        {
            _billetes = new List<Billete>();
        }

        public Vuelo(string codigo, DateTime fecha_salida, DateTime fecha_llegada, Aeropuerto origen, Aeropuerto destino):this()
        {
            
            _avion = null;
            _codigo = codigo;
            _fecha_llegada = fecha_llegada;
            _fecha_salida = fecha_salida;
            _aeropuerto_origen = origen;
            _aeropuerto_destino = destino;
        }

        public Vuelo(
        string codigo,
        DateTime fecha_salida,
        DateTime fecha_llegada,
        Aeropuerto origen,
        Aeropuerto destino,
        Avion avion)
            : this(codigo, fecha_salida, fecha_llegada, origen, destino)
        {
            _avion = avion;
        }
       
        
        public string Descriptor
        {
            get
            {
                return _aeropuerto_origen.Codigo + " "
                    + _aeropuerto_destino.Codigo + " " + _fecha_salida.ToString();
            }
        }

        public override string ToString()
        {
            return Descriptor;
        }

        public List<Asiento> AsientosDisponibles()
        {
            List<Asiento> asientos = (from Asiento a in _avion.Asientos()
                                      where !(from Billete b in _billetes
                                              where b.Vuelo == this
                                              select b.Asiento).Contains(a)
                                      select a).ToList<Asiento>();

            return asientos;
            
        }

        public bool SirvePara(string  origen, string destino, DateTime fecha)
        {
            return (
                (string.Compare(_aeropuerto_origen.Codigo, origen, true)==0 || string.Compare(_aeropuerto_origen.Ciudad, origen, true)==0) &&
                (string.Compare(_aeropuerto_destino.Codigo, destino, true)==0 || string.Compare(_aeropuerto_destino.Ciudad, destino, true)==0) &&                
                _fecha_salida >= fecha);
        }



        #region IComparable Members

        public int CompareTo(object obj)
        {
            throw new NotImplementedException();
        }

        #endregion

        public override bool Equals(object obj)
        {
            if (obj == null) 
                return this == null;

            if (obj is Vuelo)
            {
                Vuelo v = (Vuelo)obj;
                return this._avion.CompareTo(v._avion) == 0 &&
                    this._aeropuerto_destino.CompareTo(v._aeropuerto_destino) == 0 &&
                    this._aeropuerto_origen.CompareTo(v._aeropuerto_origen) == 0 &&
                    this._fecha_salida.CompareTo(v._fecha_salida) == 0 &&
                    this._fecha_salida.CompareTo(v._fecha_llegada) == 0;
            }
            else return false;
        }

        public override int GetHashCode()
        {
            return (_aeropuerto_destino.ToString() +
                _aeropuerto_origen.ToString() +
                _fecha_llegada.ToString() +
                _fecha_salida.ToString()).GetHashCode();
        }

        public string GetXml()
        {
            StringBuilder sb = new StringBuilder("<Vuelo>");
            sb.AppendFormat("<Codigo>{0}</Codigo>", _codigo);
            sb.AppendFormat("<Descriptor>{0}</Descriptor>", Descriptor);
            sb.AppendFormat("<Llegada>{0}</Llegada>", _fecha_llegada.ToString());
            sb.Append("</Vuelo>");
            return sb.ToString();
        }
    }
}
